home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 334_02 / latex.trm < prev    next >
Text File  |  1991-02-04  |  18KB  |  639 lines

  1. /* GNUPLOT - latex.trm */
  2. /*
  3.  * Copyright (C) 1990   
  4.  *
  5.  * Permission to use, copy, and distribute this software and its
  6.  * documentation for any purpose with or without fee is hereby granted, 
  7.  * provided that the above copyright notice appear in all copies and 
  8.  * that both that copyright notice and this permission notice appear 
  9.  * in supporting documentation.
  10.  *
  11.  * Permission to modify the software is granted, but not the right to
  12.  * distribute the modified code.  Modifications are to be distributed 
  13.  * as patches to released version.
  14.  *  
  15.  * This software  is provided "as is" without express or implied warranty.
  16.  * 
  17.  * This file is included by ../term.c.
  18.  *
  19.  * This terminal driver supports:
  20.  *   LaTeX pictures (latex).
  21.  *   LaTeX pictures with emTeX specials (emtex). 
  22.  *
  23.  * AUTHORS
  24.  *   David Kotz, Russell Lang
  25.  *
  26.  * send your comments or suggestions to (pixar!info-gnuplot@sun.com).
  27.  * 
  28.  */
  29.  
  30. /* modified to optimize use of \rule for long lines */
  31.  
  32. /* the following LATEX driver has been modified by 
  33.    Russell Lang, eln272v@monu1.cc.monash.oz from the
  34.    GnuTeX 1.3 driver by David Kotz, dfk@cs.duke.edu
  35.    And further extended by David Kotz  */
  36.  
  37.  
  38. #define LATEX_PTS_PER_INCH (72.27)
  39. #define DOTS_PER_INCH (300)    /* resolution of printer we expect to use */
  40. #define LATEX_UNIT (LATEX_PTS_PER_INCH/DOTS_PER_INCH) /* dot size in pt */
  41.  
  42. /* 5 inches wide by 3 inches high (default) */
  43. #define LATEX_XMAX (5*DOTS_PER_INCH)  /* (LATEX_PTS_PER_INCH/LATEX_UNIT*5.0) */
  44. #define LATEX_YMAX (3*DOTS_PER_INCH)  /* (LATEX_PTS_PER_INCH/LATEX_UNIT*3.0) */
  45.  
  46. #define LATEX_HTIC (5*DOTS_PER_INCH/72)        /* (5./LATEX_UNIT) */
  47. #define LATEX_VTIC (5*DOTS_PER_INCH/72)        /* (5./LATEX_UNIT) */
  48. #define LATEX_HCHAR (DOTS_PER_INCH*53/10/72)    /* (5.3/LATEX_UNIT) */
  49. #define LATEX_VCHAR (DOTS_PER_INCH*11/72)    /* (11./LATEX_UNIT) */
  50.  
  51. static int LATEX_posx;
  52. static int LATEX_posy;
  53. enum JUSTIFY latex_justify=LEFT;
  54. static int latex_angle=0;
  55.  
  56. /* Default line-drawing character */
  57. /* the definition of plotpoint varies with linetype */
  58. #define LATEX_DOT "\\usebox{\\plotpoint}"
  59. #define LATEX_TINY_DOT "\\rule{.1pt}{.1pt}" /* for dots plot style */
  60.  
  61. /* POINTS */
  62. #define LATEX_POINT_TYPES 12    /* we supply more point types */
  63. static char *LATEX_points[] = {
  64.     "\\raisebox{-1.2pt}{\\makebox(0,0){$\\Diamond$}}",
  65.     "\\makebox(0,0){$+$}",
  66.     "\\raisebox{-1.2pt}{\\makebox(0,0){$\\Box$}}",
  67.     "\\makebox(0,0){$\\times$}",
  68.     "\\makebox(0,0){$\\triangle$}",
  69.     "\\makebox(0,0){$\\star$}",
  70.     "\\circle{12}", "\\circle{18}", "\\circle{24}",
  71.     "\\circle*{12}", "\\circle*{18}", "\\circle*{24}"
  72. };
  73.  
  74. /* LINES */
  75. static int LATEX_type;        /* negative types use real lines */
  76. #define LATEX_LINE_TYPES 6    /* number of line types below */
  77. #define LATEX_THIN_LINE 0    /* the thinnest solid line type */
  78. static struct {
  79.     float size;            /* size of dot, or thick of line in points */
  80.     float dotspace;            /* inter-dot space in points; 0 for lines */
  81. } LATEX_lines[] = {
  82.     {.4, 0.0},                /* thin solid line */
  83.     {1.0, 0.0},                /* thick solid line */
  84.     {2.0, 0.0},                /* Thick solid line */
  85.     {.4, 5.0},                /* dotted line */
  86.     {.4, 10.0},                /* widely dotted line */
  87.     {.4, 15.0}                /* really widely dotted line */
  88. };
  89. /* for drawing dotted and solid lines */
  90. static void LATEX_dot_line();
  91. static void LATEX_solid_line();
  92. static void LATEX_rule();
  93. #define LATEX_flushrule() LATEX_rule(2, 0.,0.,0.,0.) /* flush old rule */
  94. static BOOLEAN LATEX_moved = TRUE;    /* pen is up after move */
  95. static float LATEX_dotsize;    /* size of LATEX_DOT in units */
  96.  
  97. #ifdef EMTEX
  98. BOOLEAN emtex=FALSE; /* not currently using emtex */
  99. static void EMTEX_solid_line();
  100. #endif
  101.  
  102. /* ARROWS */
  103. /* the set of non-vertical/non-horizontal LaTeX vector slopes */
  104. /* except negatives - they are handled specially */
  105. static struct vslope {
  106.     int dx, dy;
  107. } LATEX_slopes[] = {
  108.     {1,1}, {1,2}, {1,3}, {1,4},
  109.     {2,1}, {2,3},
  110.     {3,1}, {3,2}, {3,4},
  111.     {4,1}, {4,3},
  112.     {0,0}                    /* terminator */
  113. };
  114. static void best_latex_arrow(); /* figure out the best arrow */
  115.  
  116. LATEX_init()
  117. {
  118. #ifdef EMTEX
  119.     emtex = FALSE;
  120. #endif
  121.     LATEX_posx = LATEX_posy = 0;
  122.     LATEX_linetype(-1);
  123.     fprintf(outfile, "%% GNUPLOT: LaTeX picture\n");
  124.     fprintf(outfile, "\\setlength{\\unitlength}{%fpt}\n", LATEX_UNIT);
  125. }
  126.  
  127.  
  128. LATEX_scale(xs, ys)
  129.     float xs, ys;            /* scaling factors */
  130. {
  131.     register struct termentry *t = &term_tbl[term];
  132.  
  133.     /* we change the table for use in graphics.c and LATEX_graphics */
  134.     t->xmax = (unsigned int)(LATEX_XMAX * xs);
  135.     t->ymax = (unsigned int)(LATEX_YMAX * ys);
  136.  
  137.     return(TRUE);
  138. }
  139.  
  140. LATEX_graphics()
  141. {
  142.     register struct termentry *t = &term_tbl[term];
  143.  
  144.     fprintf(outfile, "\\begin{picture}(%d,%d)(0,0)\n", t->xmax, t->ymax);
  145.     fprintf(outfile, "\\tenrm\n");
  146.     fprintf(outfile, 
  147.           "\\ifx\\plotpoint\\undefined\\newsavebox{\\plotpoint}\\fi\n");
  148. }
  149.  
  150.  
  151. LATEX_text()
  152. {
  153.     LATEX_flushrule();
  154.     fprintf(outfile, "\\end{picture}\n");
  155. }
  156.  
  157.  
  158. LATEX_linetype(linetype)
  159.     int linetype;
  160. {
  161.     if (linetype >= LATEX_LINE_TYPES)
  162.      linetype %= LATEX_LINE_TYPES;
  163.  
  164. #ifdef EMTEX
  165.     if (!emtex)
  166. #endif
  167.     LATEX_flushrule();
  168.  
  169.     if (linetype >= 0 && 
  170.        (LATEX_type < 0 ||
  171.         LATEX_lines[linetype].size != LATEX_lines[LATEX_type].size)) {
  172.         /* redefine \plotpoint */
  173.         fprintf(outfile, 
  174.             "\\sbox{\\plotpoint}{\\rule[%.3fpt]{%.3fpt}{%.3fpt}}%%\n",
  175.             -LATEX_lines[linetype].size/2,
  176.             LATEX_lines[linetype].size,
  177.             LATEX_lines[linetype].size);
  178. #ifdef EMTEX
  179.         if (emtex)         /* change line width */
  180.             fprintf(outfile, "\\special{em:linewidth %.1fpt}%%\n",
  181.                 LATEX_lines[linetype].size);
  182. #endif
  183.     }
  184.     
  185.     LATEX_type = linetype;
  186.     LATEX_dotsize 
  187.      = ((linetype >= 0) ? LATEX_lines[linetype].size / LATEX_UNIT : 0);
  188.     LATEX_moved = TRUE;            /* reset */
  189. }
  190.  
  191.  
  192. LATEX_move(x,y)
  193.     unsigned int x,y;
  194. {
  195.     LATEX_posx = x;
  196.     LATEX_posy = y;
  197.     LATEX_moved = TRUE;            /* reset */
  198. }
  199.  
  200.  
  201. LATEX_point(x,y, number)        /* version of line_and_point */
  202.     unsigned int x,y;
  203.     int number;                /* type of point */
  204. {
  205.     LATEX_move(x,y);
  206.     
  207.     /* Print the character defined by 'number'; number < 0 means 
  208.       to use a dot, otherwise one of the defined points. */
  209.     fprintf(outfile, "\\put(%d,%d){%s}\n", x, y, 
  210.           (number < 0 ? LATEX_TINY_DOT
  211.            : LATEX_points[number % LATEX_POINT_TYPES]));
  212. }
  213.  
  214.  
  215. LATEX_vector(ux,uy)
  216.     unsigned int ux,uy;
  217. {
  218.     /* Negative linestyles are straight lines for frame and axes. */
  219.     /* These are vertical and horizontal lines only. */
  220.     if (LATEX_type < 0) {
  221.        int x=ux, y=uy;
  222.        if (x == LATEX_posx) { /* vertical */
  223.           fprintf(outfile, "\\put(%d,%d){\\line(0,%d){%d}}\n",
  224.                 LATEX_posx, LATEX_posy, 
  225.                 sign(y - LATEX_posy), abs(y - LATEX_posy));
  226.        } else if (y == LATEX_posy) { /* horizontal */
  227.           fprintf(outfile, "\\put(%d,%d){\\line(%d,0){%d}}\n",
  228.                 LATEX_posx, LATEX_posy, 
  229.                 sign(x - LATEX_posx), abs(x - LATEX_posx));
  230.        }
  231.     } else {                /* drawing real curves */
  232.        if (LATEX_lines[LATEX_type].dotspace == 0.0)
  233. #ifdef EMTEX
  234.         if (emtex)
  235.            EMTEX_solid_line(LATEX_posx, (int)ux, LATEX_posy, (int)uy);
  236.         else
  237. #endif
  238.            LATEX_solid_line(LATEX_posx, (int)ux, LATEX_posy, (int)uy);
  239.        else
  240.         LATEX_dot_line(LATEX_posx, (int)ux, LATEX_posy, (int)uy);
  241.     }
  242.     LATEX_posx = ux;
  243.     LATEX_posy = uy;
  244. }
  245.  
  246. static void
  247. LATEX_solid_line(x1,x2, y1,y2)
  248.     int x1,x2, y1,y2;
  249. {
  250.     float slope;
  251.     int inc;
  252.     float next;
  253.     float x,y;
  254.     int code;                /* possibly combine with previous rule */
  255.  
  256.     /* we draw a solid line using the thickness for this linetype */
  257.     /* we do it with lots of \\rules */
  258.  
  259.     if (x1 == x2 && y1 == y2) { /* zero-length line - just a dot */
  260.        if (LATEX_moved) {
  261.           LATEX_flushrule();
  262.           /* plot a dot */
  263.           fprintf(outfile, "\\put(%u,%u){%s}\n", x1, y1, LATEX_DOT);
  264.        }
  265.     } else {
  266.        code = (LATEX_moved ? 0 : 1); /* no combine after move */
  267.        if (x1 == x2)        /* vertical line - special case */
  268.         LATEX_rule(code, (float)x1, (float)y1, LATEX_dotsize, (float)y2-y1)